package cn.rulian.base.auth.controller;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import jxl.Workbook;
import jxl.format.Alignment;
import jxl.format.Border;
import jxl.format.BorderLineStyle;
import jxl.format.Colour;
import jxl.format.VerticalAlignment;
import jxl.write.Label;
import jxl.write.WritableCellFormat;
import jxl.write.WritableFont;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import cn.rulian.base.auth.bo.Organ;
import cn.rulian.base.auth.bo.Role;
import cn.rulian.base.auth.bo.User;
import cn.rulian.base.auth.dao.UserDao;
import cn.rulian.base.auth.service.OrganService;
import cn.rulian.base.auth.service.RoleService;
import cn.rulian.base.auth.service.UserService;
import cn.rulian.base.auth.vo.UserVo;
import cn.rulian.base.common.dto.ExcelBook;
import cn.rulian.base.common.dto.ExcelSheet;
import cn.rulian.base.common.dto.Message;
import cn.rulian.base.common.util.MD5Util;
import cn.rulian.base.common.util.xx;
import cn.rulian.base.common.vo.Result;

/**
 * 用户管理 Controller
 */

@Controller
@RequestMapping("/base/auth/user")
public class UserController {
	
	@Autowired
	private UserService service;

	@Autowired
	private UserDao dao;
	
	@Autowired
	private OrganService organService;
	
	@Autowired
	private RoleService roleService;
	
	private final String path="base/auth/user_"; //页面基本路径

	/**
	 * 页面基本路径
	 */
	private String getPath()
	{
		return path;
	}
	
	/**
	 * 列表页面
	 */
	@RequestMapping("/listPage")
	public String listPage() {
		return this.getPath()+"list";
	}
	
	/**
	 * 列表页面（机构内用户管理）
	 */
	@RequestMapping("/listPage2")
	public String listPage2(Model model, Long organId) {
		model.addAttribute("organId", organId);
		return this.getPath()+"list2";
	}

	/**
	 * 查询
	 */
	@RequestMapping("/listData")
	@ResponseBody
	public Result listData(UserVo vo) {
		Result result = service.query(vo);
		@SuppressWarnings("unchecked")
		List<User> ls = result.getRows();
		for(User bo:ls)
		{
			bo.setOrgan(null);
			bo.setRoleList(null);
		}
		return result;
	}

	/**
	 * 增加页面
	 */
	@RequestMapping("/addPage")
	public String addPage(Model model, Long organId) {
		if(organId != null)
		{
			model.addAttribute("organId", organId);
		}
		
		return this.getPath()+"add";
	}

	/**
	 * 增加
	 */
	@RequestMapping("/add")
	@ResponseBody
	public Message add(UserVo vo,String roleIds,Long organId) {
		Message rm = new Message();
		User bo = vo.getObj();
		
		User other = dao.findFirstByUsername(bo.getUsername());
		if(other != null)
		{
			rm.setMsg("用户名已存在，请修改！");
			rm.setCode(Message._ERROR);
			return rm;
		}
		
		try {
			processRoleAndOrgan(roleIds,organId, bo); //加工处理“角色”和“机构”相关属性
			bo.setAddTime(new Date());
			bo.setPassword(MD5Util.MD5(bo.getPassword())); //密码加密处理
			service.save(bo);
			
			rm.setMsg("保存成功！");
			rm.setCode(Message._SUCCESS);
		} catch (Exception e) {
			rm.setMsg("保存失败，异常信息：<br/>" + e.toString());
			rm.setCode(Message._ERROR);
			e.printStackTrace();
		}
		return rm;
	}

	/**
	 * 加工处理“角色”和“机构”相关属性
	 * @param roleIds
	 * @param bo
	 */
	private void processRoleAndOrgan(String roleIds, Long organId, User bo)
	{
		//角色处理
		if(!xx.isAllEmpty(roleIds))
		{
			//角色列表
			String[] arr = roleIds.split(",");
			List<Long> idList = new ArrayList<>();
			for(String idStr:arr)
			{
				idList.add(Long.valueOf(idStr));
			}
			List<Role> roleList = roleService.findAll(idList);
			bo.setRoleList(roleList);
			
			//角色显示名称
			StringBuilder roleNames = new StringBuilder();
			for(Role role:roleList)
			{
				roleNames.append(role.getName()+"，");
			}
			if(roleNames.length()>0)
			{
				bo.setRoleNames(xx.delEnd(roleNames.toString(), "，"));
			}
		}
		else
		{
			bo.setRoleList(null);
			bo.setRoleNames(null);
		}
		
		//机构处理
		if(organId !=null)
		{
			Organ organ = organService.findOne(organId);
			bo.setOrgan(organ);
			if(organ!=null)
			{
				bo.setOrganName(organ.getName());
			}
		}
		else
		{
			bo.setOrgan(null);
			bo.setOrganName(null);
		}
	}

	/**
	 * 修改页面
	 */
	@RequestMapping("/updatePage")
	public String updatePage(Model model, Long id) {
		User user = service.findOne(id);
		model.addAttribute("bo", user);
		
		//加工角色ID
		List<Role> roleList = user.getRoleList();
		StringBuilder ids = new StringBuilder();
		if(roleList != null && roleList.size() > 0)
		{
			for(Role role : roleList)
			{
				ids.append(role.getId().longValue()+",");
			}
		}
		if(ids.length()>0)
		{
			model.addAttribute("roleIds",xx.delEnd(ids.toString(), ","));
		}
		
		return this.getPath()+"update";
	}

	
	/**
	 * 修改
	 */
	@RequestMapping("/update")
	@ResponseBody
	public Message update(UserVo vo, Long id, String roleIds, Long organId) {
		Message rm = new Message();
		try {
			User obj = vo.getObj();
			
			User other = dao.findFirstByUsername(obj.getUsername());
			if(other != null && id.longValue() != other.getId().longValue())
			{
				rm.setMsg("用户名重复，请修改！");
				rm.setCode(Message._ERROR);
				return rm;
			}
			
			User bo = service.findOne(id);
			bo.setName(obj.getName());
			bo.setUsername(obj.getUsername());
			bo.setEnabled(obj.getEnabled());
			bo.setOrderNum(obj.getOrderNum());
			String password = obj.getPassword();
			if(!xx.isEmpty(password))
			{
				bo.setPassword(MD5Util.MD5(password));
			}
			
			this.processRoleAndOrgan(roleIds, organId, bo);
			service.save(bo);
			
			rm.setMsg("保存成功！");
			rm.setCode(Message._SUCCESS);
		} catch (Exception e) {
			rm.setMsg("保存失败，异常信息：<br/>" + e.toString());
			rm.setCode(Message._ERROR);
			e.printStackTrace();
		}
		return rm;
	}

	/**
	 * 删除
	 */
	@RequestMapping("/delete")
	@ResponseBody
	public Message delete(Long ids[]) {
		Message rm = new Message();
		try {
			for(Long id:ids)
			{
				service.delete(id);
			}
			
			rm.setMsg("删除成功！");
			rm.setCode(Message._SUCCESS);
		} catch (Exception e) {
			rm.setMsg("删除失败，异常信息：<br/>" + e.toString());
			rm.setCode(Message._ERROR);
			e.printStackTrace();
		}
		return rm;
	}
	
	/**
	 * 详情页面
	 */
	@RequestMapping("/detailPage")
	public String detailPage(Model model, Long id) {
		model.addAttribute("bo", service.findOne(id));
		return this.getPath()+"detail";
	}

	/**
	 * 导出Excel
	 * @throws Exception 
	 */
	@RequestMapping("/exportExcel")
	public void exportExcel(HttpServletResponse response,UserVo vo,String type) throws Exception {
		
		File file = new File("aaa.xls");
		jxl.write.WritableWorkbook book = Workbook.createWorkbook(file); //工作薄

		List<User> allDataList=service.QueryExcelData(vo); //取得导出数据
		ExcelBook<User> excelBook = this.buildExcelData(allDataList, type); //按维度进行数据加工
		String bookName = excelBook.getName(); //Excel文件名称
		List<ExcelSheet<User>> sheetList = excelBook.getSheetList(); //各Sheet列表
		if(sheetList!=null && sheetList.size() > 0)
		{
			for(ExcelSheet<User> excelSheet:sheetList)
			{
				String sheetName = excelSheet.getName(); //名称
				List<User> oneList = excelSheet.getDataList(); //数据列表
				
				jxl.write.WritableSheet sheet = book.createSheet(sheetName, 0); //工作表
				
				//设置行高
				sheet.getSettings().setDefaultRowHeight(350); //设置所有行默认行高
				sheet.setRowView(0, 700);//第1行 高度
				sheet.setRowView(1, 400);//第2行 高度
				
				//设置个别列宽
				//sheet.setColumnView(2, 12);//宽度设置
				
				//定义格式
				//主标题格式
				WritableCellFormat formatterTitle= new WritableCellFormat(); //标题格式
				formatterTitle.setAlignment(Alignment.CENTRE);//水平对齐
				formatterTitle.setVerticalAlignment(VerticalAlignment.CENTRE);//垂直对齐
				//WritableFont font = new WritableFont(WritableFont.createFont("ＭＳ Ｐゴシック"), 18, WritableFont.BOLD, false); //黑体
				WritableFont font = new WritableFont(WritableFont.TAHOMA, 18, WritableFont.BOLD, false);
				formatterTitle.setFont(font);
				
				//列标题格式
				WritableCellFormat formatterColumnTitle= new WritableCellFormat(); //列标题格式
				formatterColumnTitle.setAlignment(Alignment.CENTRE);//水平对齐
				formatterColumnTitle.setVerticalAlignment(VerticalAlignment.CENTRE);//垂直对齐
				formatterColumnTitle .setBackground(Colour.GRAY_25);//背景色
				formatterColumnTitle.setBorder(Border.ALL, BorderLineStyle.THIN);//边框线  所有边框 细线

				//普通内容格式
				WritableCellFormat formatterCon= new WritableCellFormat(); //内容格式
				formatterCon.setAlignment(Alignment.CENTRE);//水平对齐
				formatterCon.setVerticalAlignment(VerticalAlignment.CENTRE);//垂直对齐
				formatterCon.setBorder(Border.ALL, BorderLineStyle.THIN);//边框线  所有边框 细线
				
				//合计行格式
				WritableCellFormat formatterSum= new WritableCellFormat(); //合计格式
				formatterSum.setAlignment(Alignment.CENTRE);//水平对齐
				formatterSum.setVerticalAlignment(VerticalAlignment.CENTRE);//垂直对齐
				formatterSum.setBorder(Border.ALL, BorderLineStyle.THIN);//边框线  所有边框 细线
				WritableFont font_sum = new WritableFont(WritableFont.TAHOMA, 10, WritableFont.BOLD, false);
				formatterSum.setFont(font_sum);
				
				//输出标题
				sheet.mergeCells(0, 0, 6, 0); //合并单元格（标题）
				sheet.addCell(creatLabel(0,0,"用户管理（"+sheetName+"）",formatterTitle));

				//输出列标题
				int rowNum=1; //行号
				int columnNum=0; //列号
				
				sheet.addCell(creatLabel(rowNum,columnNum++,"序号",formatterColumnTitle));
				sheet.addCell(creatLabel(rowNum,columnNum++,"姓名",formatterColumnTitle));
				sheet.addCell(creatLabel(rowNum,columnNum++,"用户名",formatterColumnTitle));
				sheet.addCell(creatLabel(rowNum,columnNum++,"是否可用",formatterColumnTitle));
				sheet.addCell(creatLabel(rowNum,columnNum++,"排序号",formatterColumnTitle));
				sheet.addCell(creatLabel(rowNum,columnNum++,"角色",formatterColumnTitle));
				sheet.addCell(creatLabel(rowNum,columnNum++,"增加时间",formatterColumnTitle));
				
				//合计项
			
				if(oneList != null && oneList.size() > 0)
				{
					SimpleDateFormat formatterDate = new SimpleDateFormat("yyyy-MM-dd"); //日期格式化
					//SimpleDateFormat formatterTime = new SimpleDateFormat("yyyy-MM-dd HH:mm"); //时间格式化
					//SimpleDateFormat formatterTime2 = new SimpleDateFormat("yyyy-MM-dd HH:mm"); //时间格式化2
					
					//展示数据
					String nameStr = ""; // 姓名
					String usernameStr = ""; // 用户名
					String enabledStr = ""; // 是否可用
					String orderNumStr = ""; // 排序号
					String roleListStr = ""; // 角色
					String addTimeStr = ""; // 增加时间
					
					for(int i = 0; i < oneList.size(); i++)
			    	{
						User bo = oneList.get(i); 
						rowNum++;
						columnNum=0;
						
						//展示数据初始化
						nameStr = ""; // 姓名
						usernameStr = ""; // 用户名
						enabledStr = ""; // 是否可用
						orderNumStr = ""; // 排序号
						roleListStr = ""; // 角色
						addTimeStr = ""; // 增加时间
						
						//展示数据赋值
						if(bo.getName() != null){	nameStr = bo.getName().toString();	} //姓名
	           		
						if(bo.getUsername() != null){	usernameStr = bo.getUsername().toString();	} //用户名
	           		
						if(bo.getEnabled() != null){	enabledStr = bo.getEnabled()?"开":"关";		} //是否可用
	           		
						if(bo.getOrderNum() != null){	orderNumStr = bo.getOrderNum().toString();	} //排序号
	           		
						if(bo.getRoleList() != null){	roleListStr = bo.getRoleList().toString();	} //角色
	           		
						if(bo.getAddTime() != null){	addTimeStr = formatterDate.format(bo.getAddTime());	} //增加时间
	           		
	           	
						
						
						//输出一行数据
			    		sheet.addCell(creatLabel(rowNum,columnNum++,(i+1)+"",formatterCon)); 
			    		sheet.addCell(creatLabel(rowNum,columnNum++,nameStr ,formatterCon)); // 姓名
			    		sheet.addCell(creatLabel(rowNum,columnNum++,usernameStr ,formatterCon)); // 用户名
			    		sheet.addCell(creatLabel(rowNum,columnNum++,enabledStr ,formatterCon)); // 是否可用
			    		sheet.addCell(creatLabel(rowNum,columnNum++,orderNumStr ,formatterCon)); // 排序号
			    		sheet.addCell(creatLabel(rowNum,columnNum++,roleListStr ,formatterCon)); // 角色
			    		sheet.addCell(creatLabel(rowNum,columnNum++,addTimeStr ,formatterCon)); // 增加时间
			    		
			    		//合计项累加
			    	}
					
					//表格增加合计项
					rowNum++;
					columnNum = 0;
					sheet.setRowView(rowNum, 400);//合计行 高度
		    		
		    		sheet.addCell(creatLabel(rowNum,columnNum++,"",formatterSum)); 
		    		sheet.addCell(creatLabel(rowNum,columnNum++,"" ,formatterSum)); // 姓名
		    		sheet.addCell(creatLabel(rowNum,columnNum++,"" ,formatterSum)); // 用户名
		    		sheet.addCell(creatLabel(rowNum,columnNum++,"" ,formatterSum)); // 是否可用
		    		sheet.addCell(creatLabel(rowNum,columnNum++,"" ,formatterSum)); // 排序号
		    		sheet.addCell(creatLabel(rowNum,columnNum++,"" ,formatterSum)); // 角色
		    		sheet.addCell(creatLabel(rowNum,columnNum++,"" ,formatterSum)); // 增加时间
    		
				}
			}
		}
		
		//-------------------------------

		book.write();
		book.close();

		FileInputStream f = new FileInputStream(file);
		byte[] fb = new byte[f.available()];
		f.read(fb);
		response.setHeader("Content-disposition", "attachment; filename=" + new String((bookName + ".xls").getBytes("gb2312"), "iso8859-1"));
		ByteArrayInputStream bais = new ByteArrayInputStream(fb);
		int b;
		while ((b = bais.read()) != -1)
		{
			response.getOutputStream().write(b);
		}
		response.getOutputStream().flush();
		f.close();
		
	}
	
	private Label creatLabel(int rowNum,int columnNum,String con,WritableCellFormat formatter) //行，列，内容 ，格式化
	{  
		 return new Label(columnNum, rowNum, con,formatter);   
	}  
	
	/**
	 * 从不同维度，构建Excel导出所需要的数据
	 */
	private ExcelBook<User> buildExcelData(List<User> list,String exportType)
	{
		ExcelBook<User> book = new ExcelBook<User>();
		
		if("all".equals(exportType))
		{//不分表
			book.setName("用户管理");
		}

		//根据维度（sheetName）不同，对数据分表
		Map<String,List<User>> map =new HashMap<String,List<User>>(); 
		String sheetName = null;
		for(User bo:list)
		{
		
	
			if("all".equals(exportType))
			{//不分表
				sheetName="全部";
			}
			
			List<User> dataList = map.get(sheetName);
			if(dataList==null)
			{
				dataList = new ArrayList<>();
			}
			dataList.add(bo);
			map.put(sheetName, dataList);
		}
		
		//转换Map,得到数据表列表
		List<ExcelSheet<User>> sheetList = new ArrayList<>();
		for (Map.Entry<String, List<User>> m : map.entrySet()) 
		{
			ExcelSheet<User> sheet = new ExcelSheet<User>();
			sheet.setName(m.getKey());
			sheet.setDataList(m.getValue());
			sheetList.add(sheet);
		} 
		
		if(sheetList.size()==0)
		{
			ExcelSheet<User> sheet = new ExcelSheet<User>();
			sheet.setName("全部");
			sheet.setDataList(new ArrayList<User>());
			sheetList.add(sheet);
		}
		
		book.setSheetList(sheetList);
		
		return book;
	}
	
}
